﻿//-------------------------------------------------------------------
//	Copyright (c) 2010-2014  Zhirnov Andrey
//	This file is part of the "UX Standard Lib" project.
//	See copyright notice in "UX_STL_Core.h".
//-------------------------------------------------------------------

#ifndef _UXS_ERROR_DEFINES_H
#define _UXS_ERROR_DEFINES_H

#pragma once

#include "Defines.h"


// helpers //
#define __UX_GET_FIRST( _1_, ... )			_1_
#define __UX_GET_SECOND( _1_, _2_, ... )	_2_

#define __UX_LOG( _text_, _level_ ) \
	LOG( (::UX_STL::UXTypes::string( "Error: " ) << _text_ << ", in function: " UX_FUNCTION_NAME ".").cstr(), (_level_) )



// release & debug //
#ifdef __UX_FAST__

#	define __UX_RETURN_ERR( _text_, _ret_, ... )
		{ return (_ret_); }

#	define __UX_CHECK_ERRX( _check_, _text_, _level_, _ret_ ) \
		{ (void)( _check_ ); }

#	define __UX_CHECK_WARN( _check_, _text_, _level_ ) \
		{ (void)( _check_ ); }

#else
		
#	define __UX_RETURN_ERR( _text_, _ret_, ... ) \
		{ __UX_LOG( _text_, __UX_OPT_DEFAULT_LOG_ERROR );  return (_ret_); }

#	define __UX_CHECK_ERRX( _check_, _text_, _level_, _ret_ ) \
		{ \
			if ( not (_check_) ) { \
				__UX_LOG( _text_, (_level_) ); \
				return (_ret_); \
			} \
		}

#	define __UX_CHECK_WARN( _check_, _text_, _level_ ) \
		{ \
			if ( not (_check_) ) { \
				__UX_LOG( _text_, (_level_) ); \
			} \
		}

#endif	// __UX_FAST__
		

// return error
#define RETURN_ERR( ... ) \
	__UX_RETURN_ERR( __UX_GET_FIRST( __VA_ARGS__ ), __UX_GET_SECOND( __VA_ARGS__, false ) )


// check and return error if false
#define __UX_CHECK_ERR( _func_, _ret_, ... ) \
	__UX_CHECK_ERRX( (_func_), TO_ANSI_STRING( _func_ ), __UX_OPT_DEFAULT_LOG_ERROR, (_ret_)  )

#define CHECK_ERR( ... ) \
	__UX_CHECK_ERR( __UX_GET_FIRST( __VA_ARGS__ ), __UX_GET_SECOND( __VA_ARGS__, false ) )


// check only
#define CHECK( _func_ ) \
	__UX_CHECK_WARN( (_func_), TO_ANSI_STRING( _func_ ), __UX_OPT_DEFAULT_LOG_ERROR )


// debug only //
#ifdef __UX_DEBUG__

	// check and return error if false
#	define __UX_DBG_CHECK_ERR( _func_, _ret_, ... ) \
		__UX_CHECK_ERRX( (_func_), TO_ANSI_STRING( _func_ ), __UX_OPT_DEFAULT_LOG_WARNING, (_ret_)  )

#	define DBG_CHECK_ERR( ... ) \
		__UX_DBG_CHECK_ERR( __UX_GET_FIRST( __VA_ARGS__ ), __UX_GET_SECOND( __VA_ARGS__, false ) )
	
	// check only
#	define DBG_CHECK( ... ) \
		__UX_CHECK_WARN( (_func_), TO_ANSI_STRING( _func_ ), __UX_OPT_DEFAULT_LOG_WARNING )

#else
	
	// check and return error if false
#	define DBG_CHECK_ERR( ... )						{}

	// check only
#	define DBG_CHECK( ... )							{}

#endif



//----------------------- Critical Errors -------------------------//

// Check Memory Allocation Exception
#define CHECK_ALLOC_RE( _func, _on_exc, _text ) \
	TRY { \
		_func; \
	} CATCH( ..., \
	{ \
		LOG_WARNING( _text, ::UX_STL::e_log_msg::DEF_ERROR ); \
		_on_exc; \
	} )

#define CHECK_ALLOC_RT( _func, _text, _ret )	CHECK_ALLOC_RE( _func, return _ret, _text )
#define CHECK_ALLOC_B( _func, _res )			CHECK_ALLOC_RE( { _res = true; _func; }, _res = false, "Can't allocate memory" )
#define CHECK_ALLOC_T( _func, _text )			CHECK_ALLOC_RT( _func, _text, false )
#define CHECK_ALLOC_R( _func, _ret )			CHECK_ALLOC_RT( _func, "Can't allocate memory in function: \""#_func"\"", _ret )
#define CHECK_ALLOC( _func )					CHECK_ALLOC_R( _func, false )



//-------------------------------------------------------------------

#endif	// _UXS_ERROR_DEFINES_H